///////////////////////////////////////////////////
//
// Do not modify this file!
//
///////////////////////////////////////////////////

enum process_state { 
  READY, RUNNING, WAITING
};

/*
 * ignore this please!
 */
struct process_action {
  int sleep_at;
  int sleep_for;
};

/*
 * process control block
 */
struct PCB {
  /* 
   * link field used to put PCB on ready list or a wait list; you will
   * need to change this field
   */
  struct PCB *link;

  /*
   * current state: you may read or write it
   */
  enum process_state state;

  /*
   * a string providing this process's name, you may read it but do
   * not change it
   */
  char *id;

  // ignore these fields! you should not read or write them
  struct PCB *all;
  int slice_left;
  int runtime;
  struct process_action *action;
};

/*
 * currently running process-- you may change the state of this
 * process, but do not make "current" point to a different PCB (the
 * dispatch routine takes care of that)
 */
struct PCB *current;

/* 
 * singly linked list of processes ready to run, using the PCB's link
 * field
 */
struct PCB *ready_list;

///////////////////////////////////////////////////
// kernel library functions you may call

/*
 * returns current time in ticks
 */
int get_current_time (void);

/*
 * we no longer want to run the current process (for example because
 * it has been put to sleep and is in the WAITING state), so find a 
 * new process and start running it
 *
 * precondition: current->state == RUNNING || current->state == WAITING
 *
 */
void dispatch (void);

/* 
 * allocate memory, works just like malloc()
 */
void *kmalloc (int);

/* 
 * free memory, works just like free()
 */
void kfree (void *);

///////////////////////////////////////////////////
// you write these

/*
 * if the argument is positive, block the current process for the
 * specified number of ticks
 *
 * if the argument is 0 or negative, do nothing
 */
void sys_sleep (int);

/*
 * the OS calls this function once per tick; you use it to wake up
 * sleeping processes
 *
 * an awakened process should be put at the head of the ready list
 *
 * make sure you wake up all processes whose time is up, not just
 * one of them
 */
void timer_sleep (void);

/*
 * returns number of processes that are currently waiting on sleep()
 * calls
 */
int num_sleeping (void);

///////////////////////////////////////////////////
// may be handy -- but don't #include any other files

#include <stdio.h>
#include <assert.h>

///////////////////////////////////////////////////
